package org.acghub.mtdb.test;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.ThreadLocalRandom;

public class CompletableFutureParentChildTasks {

    public static void main(String[] args) {
        // 创建父任务
        CompletableFuture<String> parentTask = CompletableFuture.supplyAsync(() -> {
            System.out.println("[父任务] 开始执行 - 线程: " + Thread.currentThread().getName());
            // 模拟耗时操作
            try {
                TimeUnit.MILLISECONDS.sleep(500);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            System.out.println("[父任务] 完成");
            return "父任务结果";
        });

        // 创建三个子任务，依赖父任务的结果
        CompletableFuture<String> childTask1 = parentTask.thenApplyAsync(parentResult -> {
            System.out.println("[子任务1] 开始执行 - 父任务结果: " + parentResult + " - 线程: " + Thread.currentThread().getName());
            // 模拟耗时操作
            try {
                TimeUnit.MILLISECONDS.sleep(ThreadLocalRandom.current().nextInt(300, 800));
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            System.out.println("[子任务1] 完成");
            return "子任务1结果";
        });

        CompletableFuture<String> childTask2 = parentTask.thenApplyAsync(parentResult -> {
            System.out.println("[子任务2] 开始执行 - 父任务结果: " + parentResult + " - 线程: " + Thread.currentThread().getName());
            // 模拟耗时操作
            try {
                TimeUnit.MILLISECONDS.sleep(ThreadLocalRandom.current().nextInt(300, 800));
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            System.out.println("[子任务2] 完成");
            return "子任务2结果";
        });

        CompletableFuture<String> childTask3 = parentTask.thenApplyAsync(parentResult -> {
            System.out.println("[子任务3] 开始执行 - 父任务结果: " + parentResult + " - 线程: " + Thread.currentThread().getName());
            // 模拟耗时操作
            try {
                TimeUnit.MILLISECONDS.sleep(ThreadLocalRandom.current().nextInt(300, 800));
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            System.out.println("[子任务3] 完成");
            return "子任务3结果";
        });

        // 合并所有子任务结果
        CompletableFuture<Void> allChildren = CompletableFuture.allOf(childTask1, childTask2, childTask3);
        
        // 最终任务：处理所有子任务结果
        CompletableFuture<String> finalTask = allChildren.thenApplyAsync(v -> {
            System.out.println("[最终任务] 开始处理子任务结果 - 线程: " + Thread.currentThread().getName());
            
            try {
                String result1 = childTask1.get();
                String result2 = childTask2.get();
                String result3 = childTask3.get();
                
                System.out.println("├── 子任务1结果: " + result1);
                System.out.println("├── 子任务2结果: " + result2);
                System.out.println("└── 子任务3结果: " + result3);
                
                return "最终结果: " + result1 + " + " + result2 + " + " + result3;
            } catch (InterruptedException | ExecutionException e) {
                throw new RuntimeException("处理子任务结果时出错", e);
            }
        });

        // 等待最终任务完成并输出结果
        try {
            System.out.println("等待所有任务完成...");
            System.out.println(finalTask.get());
            System.out.println("所有任务完成！");
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }
}